﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AdvanceLib.ScriptCore;
using AdvanceLib.Core;
using AdvanceLib.ClassExtensions;

namespace AdvanceLib.Extension.Root
{
    public class RootParser : IParser
    {
        #region Constructors
        public RootParser(RootProvider provider)
        {
            this._host = provider.Host;
        }
        #endregion

        #region Fields
        private ScriptHost _host;
        #endregion

        #region Methods
        public ISystemCommand GetCommand(string commandName, int parameters)
        {
            List<ISystemCommand> commands = this._host.ExtensionManager.GetSystemCommandsByName(commandName);
            ISystemCommand systemCommand = commands.First(command => command.ExpectedParameters == parameters) as ISystemCommand;

            return systemCommand;
        }
        #endregion

        #region IParser Member
        public List<ICommand> Parse(string input)
        {
            ISystemSection currentSection = null;
            List<string> paramValues = new List<string>();
            List<ICommand> result = new List<ICommand>();

            int currentLine = 0;

            LineParser lineParser = new LineParser();
            lineParser.Parse(input);

            foreach (Line line in lineParser.Lines)
            {
                currentLine++;

                if (!line.IsEmpty)
                {
                    if (line.Content.StartsWith(this._host.SystemCommandInitialization))
                    {
                        string currentLinePart = line.Parts[Constants.FIRST_INDEX];
                        string commandName = currentLinePart.Substring(this._host.SystemCommandInitialization.Length);

                        ISystemCommand sourceCommand = this.GetCommand(commandName, line.Parts.Length - 1);
                        ISystemCommand systemCommand = sourceCommand.Clone<ISystemCommand>();

                        if (systemCommand is ISystemSection)
                        {
                            currentSection = systemCommand as ISystemSection;
                            currentSection.BaseLine = currentLine;
                        }

                        systemCommand.ParameterValues = line.Parts.Skip(1).ToArray();                        

                        result.Add(systemCommand as ICommand);
                    }
                    else
                    {
                        currentSection.Source += line.Content + Constants.NEW_LINE;
                    }
                }
            }

            return result;
        }
        public string Deparse(List<ICommand> input)
        {
            StringBuilder output = new StringBuilder();

            foreach (ICommand command in input)
            {
                if (command is ISystemCommand)
                {
                    ISystemCommand systemCommand = command as ISystemCommand;

                    output.Append(this._host.SystemCommandInitialization);
                    output.Append(systemCommand.Name);

                    foreach (string param in systemCommand.ParameterValues)
                    {
                        output.Append(Constants.WHITE_SPACE);
                        output.Append(param);
                    }
                }
                if (command is ISystemSection)
                {
                    ISystemSection systemSection = command as ISystemSection;

                    output.Append(systemSection.Source);
                }
                output.Append(Constants.NEW_LINE);
            }

            return output.ToString();
        }
        #endregion
    }
}
